home *** CD-ROM | disk | FTP | other *** search
/ Amiga Game-Power / Amiga Game-Power.iso / pd mix ii / sprite ed / ing / ing.c < prev    next >
C/C++ Source or Header  |  1994-05-20  |  7KB  |  298 lines

  1. /* :ts=8 bk=0
  2.  * ing.c:  The next logical step in "Boing"-type display hacks.
  3.  *
  4.  * Written by Leo L. Schwab        8702.3
  5.  * Released into the public domain, but please keep the original author's
  6.  * name on it.
  7.  *
  8.  * Note: After preliminary experiments, I get the impression that this could
  9.  * somehow be faster.  Suggestions appreciated.
  10.  */
  11.  
  12. #include <exec/types.h>
  13. #include <intuition/intuition.h>
  14. #include <math.h>
  15.  
  16. #define    DEPTH        2
  17.  
  18.  
  19. extern void    *OpenLibrary(), *OpenWindow(), *OpenScreen(), *AllocRaster(),
  20.         *GetMsg(), *malloc();
  21. extern long    VBeamPos();
  22.  
  23.  
  24. struct NewScreen scrdef = {
  25.     0, 0, 0, 0, DEPTH,    /*  Size filled in later  */
  26.     0, 1,
  27.     HIRES,
  28.     CUSTOMSCREEN,
  29.     NULL,
  30.     NULL,            /*  Title filled in later  */
  31.     NULL, NULL
  32. };
  33.  
  34. struct NewWindow windef = {
  35.     0, 30, 150, 10,
  36.     -1, -1,
  37.     CLOSEWINDOW,
  38.     WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH | SMART_REFRESH | ACTIVATE,
  39.     NULL, NULL,
  40.     "Ing!",
  41.     NULL, NULL,
  42.     0, 0, 0, 0,
  43.     WBENCHSCREEN
  44. };
  45.  
  46.  
  47. struct wlist {
  48.     struct wlist *next, *prev;
  49.     struct BitMap bitmap;
  50.     long sizx, sizy;
  51.     int maxx, maxy;
  52.     int x, y, dx, dy;
  53.     int maxdy;
  54. };
  55.  
  56.  
  57. struct Screen    *scr, *wb;
  58. struct Window    *win;
  59. struct BitMap    *bm1, bm2, barmap;
  60. struct wlist    *listbase;
  61. void        *IntuitionBase, *GfxBase;
  62.  
  63.  
  64. main ()
  65. {
  66.     struct Window        *wbwin;
  67.     struct ViewPort        *svp;
  68.     register struct BitMap    *abm;
  69.     struct BitMap        *wbbm, **vbm;
  70.     register struct wlist    *this = NULL;
  71.     struct wlist        *new;
  72.     long            wide, high, barhigh, wbhigh;
  73.     int            i;
  74.     void            *msg;
  75.  
  76.     openstuff ();
  77.     rnd ((short) -VBeamPos());
  78.     wb = win -> WScreen;    /*  Workbench screen  */
  79.     wbbm = wb -> RastPort.BitMap;
  80.     scrdef.LeftEdge = wb -> LeftEdge;
  81.     scrdef.TopEdge    = wb -> TopEdge;
  82.     scrdef.Width    = wb -> Width;
  83.     scrdef.Height    = wbhigh = wb -> Height;
  84.  
  85.     /*  Scan all windows in workbench screen  */
  86.     for (wbwin = wb -> FirstWindow; wbwin; wbwin = wbwin -> NextWindow) {
  87.         if (wbwin->Flags & BACKDROP && wbwin->Flags & WBENCHWINDOW) {
  88.             scrdef.DefaultTitle = wbwin -> ScreenTitle;
  89.             continue;
  90.         }
  91.  
  92.         if (wbwin -> Height > wbhigh-21)
  93.             continue;    /*  too tall, no fun  */
  94.         if (wbwin -> Width > wb->Width - 40)
  95.             continue;    /*  too wide, no fun  */
  96.  
  97.         /*  Allocate new entry in list  */
  98.         if (!(new = malloc (sizeof (*new))))
  99.             die ("malloc failed.");
  100.         new -> prev = this;
  101.         new -> next = NULL;
  102.         if (this)
  103.             this -> next = new;
  104.         listbase = new;
  105.  
  106.         /*  Grab necessary info  */
  107.         wide = new -> sizx = wbwin -> Width;
  108.         high = new -> sizy = wbwin -> Height;
  109.         new -> maxx = wb -> Width - wide;
  110.         new -> maxy = wb -> Height - high;
  111.         new -> x = wbwin -> LeftEdge;
  112.         new -> y = wbwin -> TopEdge;
  113.         new -> dx = new -> dy = 0;
  114.  
  115.         /*
  116.          * Compute maximum initial vertical velocity.
  117.          * (Do you know how long it took me to arrive at this
  118.          * formula?)
  119.          * Note:  If gravity is anything other than one, this
  120.          * formula falls apart.
  121.          */
  122.         new -> maxdy = sqrt (2 * new->maxy + 0.25) - 0.5 + 1.0;
  123.  
  124.         /*  Create bitmap and copy window into it  */
  125.         InitBitMap (&new -> bitmap, (long) DEPTH, wide, high);
  126.         for (i=0; i<DEPTH; i++)
  127.         if (!(new -> bitmap.Planes[i] = AllocRaster (wide, high)))
  128.             die ("AllocRaster failed.");
  129.  
  130.         WindowToFront (wbwin);    /*  WindowToFront() doesn't happen  */
  131.         Delay (5L);        /*  immediately, so wait.  */
  132.         BltBitMap
  133.          (wbbm, (long) wbwin -> LeftEdge, (long) wbwin -> TopEdge,
  134.           &new -> bitmap, 0L, 0L,
  135.           wide, high, 0xC0L, 0xffL, NULL);
  136.  
  137.         this = new;
  138.     }
  139.  
  140.     /*  All windows scanned and copied, now to do the hard part  */
  141.     scr = OpenScreen (&scrdef);    /*  Clone WorkBench  */
  142.     bm1 = scr -> ViewPort.RasInfo -> BitMap;
  143.     svp = &scr -> ViewPort;
  144.  
  145.     /*  Make second set of bitplanes for double buffering  */
  146.     wide = wb -> Width;
  147.     InitBitMap (&bm2, (long) DEPTH, wide, wbhigh);
  148.     for (i=0; i<DEPTH; i++)
  149.         if (!(bm2.Planes[i] = AllocRaster (wide, wbhigh)))
  150.             die ("AllocRaster 2 failed.");
  151.     BltBitMap
  152.      (bm1, 0L, 0L, &bm2, 0L, 0L, wide, wbhigh, 0xc0L, 0xffL, NULL);
  153.  
  154.     /*  Create private bitmap to hold screen title bar  */
  155.     barhigh = wb -> BarHeight;
  156.     InitBitMap (&barmap, (long) DEPTH, wide, barhigh);
  157.     for (i=0; i<DEPTH; i++)
  158.         if (!(barmap.Planes[i] = AllocRaster (wide, barhigh)))
  159.             die ("AllocRaster 3 failed.");
  160.     BltBitMap
  161.      (bm1, 0L, 0L, &barmap, 0L, 0L, wide, barhigh, 0xc0L, 0xffL, NULL);
  162.  
  163.     i = 0;
  164.     vbm = &scr -> ViewPort.RasInfo -> BitMap;
  165.     abm = &bm2;
  166.     while (1) {
  167.         /*  Copy screen bar  */
  168.         BltBitMap (&barmap, 0L, 0L,
  169.                abm, 0L, 0L,
  170.                wide, barhigh, 0xc0L, 0xffL, NULL);
  171.         /*  Clear rest of screen  */
  172.         BltBitMap (abm, 0L, 0L,
  173.                abm, 0L, barhigh,
  174.                wide, wbhigh-barhigh, 0L, 0xffL, NULL);
  175.  
  176.         /*  Scan window copies backwards  */
  177.         for (this = listbase; this; this = this -> prev) {
  178.             if ((this -> x += this -> dx) > this -> maxx) {
  179.                 this -> x = this->maxx * 2 - this->x;
  180.                 this -> dx = -this -> dx;
  181.             } else if (this -> x < 0) {
  182.                 this -> x = -this -> x;
  183.                 this -> dx = -this -> dx;
  184.             }
  185.  
  186.             if ((this -> y += this -> dy) > this -> maxy) {
  187.                 this -> y = this -> maxy;
  188.                 this -> dy = -rnd (this->maxdy - 4) - 4;
  189.                 this -> dx = rnd (31) - 15;
  190.             } else
  191.                 this -> dy++;
  192.  
  193.             /*  Copy window image  */
  194.             BltBitMap
  195.              (&this -> bitmap, 0L, 0L,
  196.               abm, (long) this -> x, (long) this -> y,
  197.               this -> sizx, this -> sizy, 0xc0L, 0xffL, NULL);
  198.         }
  199.  
  200.         /*
  201.          * This is the hairy part.  I've tried to arrange things so
  202.          * that there will be a minimum of hashing, but under certain
  203.          * phases of the moon, it's unavoidable.  Sorry.
  204.          */
  205.         Forbid ();
  206.         if (i) {    /*  Ping  */
  207.             *vbm = bm1;
  208.             abm = &bm2;
  209.         } else {    /*  Pong  */
  210.             *vbm = &bm2;
  211.             abm = bm1;
  212.         }
  213.         i = !i;
  214.         /*  Surprise!  Intuition doesn't mind this!  */
  215.         ScrollVPort (svp);
  216.         Permit ();
  217.  
  218.         if (msg = GetMsg (win -> UserPort)) {
  219.             ReplyMsg (msg);
  220.             break;
  221.         }
  222.         WaitTOF ();
  223.     }
  224.  
  225.     /*  Restore the original  */
  226.     Forbid ();
  227.     *vbm = bm1;
  228.     ScrollVPort (svp);    /*  Ping!  */
  229.     Permit ();
  230.  
  231.     closestuff ();
  232. }
  233.  
  234.  
  235. openstuff ()
  236. {
  237.     if (!(IntuitionBase = OpenLibrary ("intuition.library", 0L))) {
  238.         printf ("Intuition missing.\n");
  239.         exit (100);
  240.     }
  241.  
  242.     if (!(GfxBase = OpenLibrary ("graphics.library", 0L))) {
  243.         printf ("Art shop closed.\n");
  244.         closestuff ();
  245.         exit (100);
  246.     }
  247.  
  248.     if (!(win = OpenWindow (&windef))) {
  249.         printf ("Window painted shut.\n");
  250.         closestuff ();
  251.         exit (100);
  252.     }
  253. }
  254.  
  255. die (str)
  256. char *str;
  257. {
  258.     puts (str);
  259.     closestuff ();
  260.     exit (100);
  261. }
  262.  
  263. closestuff ()
  264. {
  265.     register int i;
  266.  
  267.     for (i=0; i<DEPTH; i++) {
  268.         if (barmap.Planes[i])
  269.             FreeRaster (barmap.Planes[i],
  270.                     (long) wb->Width, (long) wb->BarHeight);
  271.         if (bm2.Planes[i])
  272.             FreeRaster (bm2.Planes[i],
  273.                      (long) wb->Width, (long) wb->Height);
  274.     }
  275.  
  276.     if (listbase)        freelist ();
  277.     if (scr)        CloseScreen (scr);
  278.     if (win)        CloseWindow (win);
  279.     if (GfxBase)        CloseLibrary (GfxBase);
  280.     if (IntuitionBase)    CloseLibrary (IntuitionBase);
  281. }
  282.  
  283. freelist ()
  284. {
  285.     register struct wlist *this = listbase, *tmp;
  286.     register int i;
  287.  
  288.     while (this) {
  289.         for (i=0; i<DEPTH; i++)
  290.             if (this -> bitmap.Planes[i])
  291.                 FreeRaster (this -> bitmap.Planes[i],
  292.                         this -> sizx, this -> sizy);
  293.         tmp = this;
  294.         this = this -> prev;
  295.         free (tmp);
  296.     }
  297. }
  298.